﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml;
using System.Xml.Serialization;
using System.Runtime.Serialization;
using System.Windows.Forms;
using System.ComponentModel;
using Expand.ComponentModel;

namespace SpellCaster3.Core
{
    [Serializable]
    public class Profile : IXmlSerializable, ISerializable
    {
        public static readonly Version Version = new Version(1, 0, 2, 3);

        public Profile() { }

        private TrackableList<ButtonMacro> _ButtonsMacro = new TrackableList<ButtonMacro>();

        public TrackableList<ButtonMacro> ButtonsMacro
        {
            get { return _ButtonsMacro; }
            set
            {
                if (value == null) throw new ArgumentNullException("value", "ButtonMacro collection must not be null");
                _ButtonsMacro = value;
            }
        }

        public System.Xml.Schema.XmlSchema GetSchema()
        {
            return null;
        }

        internal static Version FoundVersion { get; private set; }

        public void ReadXml(XmlReader reader)
        {
            ButtonMacro macro;
            Version version;

            _ButtonsMacro.Clear();

            version = Version.Parse(reader.GetAttribute("Version"));
            FoundVersion = version;

            if (reader.IsEmptyElement) return;

            reader.ReadStartElement(GetType().Name);
            while (true)
            {
                if (reader.NodeType == XmlNodeType.Element && reader.LocalName == ButtonsMacro.GetType().GetGenericArguments()[0].Name)
                {
                    reader.ReadStartElement(ButtonsMacro.GetType().GetGenericArguments()[0].Name);
                    macro = new ButtonMacro();
                    macro.ReadXml(reader);
                    reader.ReadEndElement();

                    _ButtonsMacro.Add(macro);
                }
                else
                    break;
            }
            reader.ReadEndElement();
        }

        public void WriteXml(XmlWriter writer)
        {
            writer.WriteAttributeString("Version", Version.ToString());
            foreach (ButtonMacro macro in ButtonsMacro)
            {
                writer.WriteStartElement(macro.GetType().Name);
                macro.WriteXml(writer);
                writer.WriteEndElement();
            }
        }

        // Deserialize
        public Profile(SerializationInfo info, StreamingContext context)
            : this()
        {
            Version version = info.GetValue("Version", Version.GetType()) as Version;
            FoundVersion = version;
            int buttonsMacroCount = info.GetInt32("ButtonsMacro.Count");
            for (int i = 0; i < buttonsMacroCount; ++i)
                _ButtonsMacro.Add(new ButtonMacro(info, context));
        }

        // Serialize
        public void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            info.AddValue("Version", Version);
            info.AddValue("ButtonsMacro.Count", ButtonsMacro.Count);
            foreach (ButtonMacro macro in ButtonsMacro)
                macro.GetObjectData(info, context);
        }
    }
}
